unit JATUIF_Component_ListBox;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Video, JATUIF_Component, JATUIF_Driver_Screen, JATUIF_Component_Button;

Type

    { TListBox }

    TListBox = class(TComponent)
      Protected
        Procedure _OnKeyPress(Key:Char); override;
        Procedure _OnMouseEnter; override;
        Procedure _OnMouseLeave; override;
        Procedure _OnClick; override;
        Procedure _OnLoseFocus; override;
        Procedure Draw; override;
      Private
        { Private Properties & Methods }
        mX1,mX2,mY1,mY2:Integer;
        Strings:TStringList;
        Btn_Up:TButton;
        Btn_Down:TButton;
        Position:Integer;
        Width:Integer;
        Height:Integer;
        UpText,DownText:String;
        BlankingPlate:String;
        Selected:Integer;
        Procedure Btn_Up_OnClick;
        Procedure Btn_Down_OnClick;
        Procedure CreateTexts;
        Procedure List_OnClick;
        Procedure SetVisible(Vis:Boolean); override;
      Public
        Constructor Create(Parent:TScreen; X1,Y1,X2,Y2:Integer);
        Procedure Add(Text:String);
        Procedure Delete(Index:Integer);
        Function GetSelectedText:String;
        Function IndexOf(Text:String):Integer;
        Function GetText(Index:Integer):String;
    end;

implementation

{ TListBox }

Constructor TListBox.Create(Parent: TScreen; X1, Y1, X2, Y2: Integer);
begin
     Strings:= TStringList.Create;
     Position:=0;
     Selected:=-1;
     If ((X2 - X1) MOD 2) = 0 then X2:= X2-1;
     Width:=X2-X1;
     While (Y2-Y1) < 2 do begin
           Y2:= Y2 + 1;
     end;
     Height:= Y2-Y1;
     CreateTexts;
     Btn_Up:= TButton.Create(Parent,X1,Y1,UpText,Black,White,Red,White);
     Btn_Down:= TButton.Create(Parent,X1,Y2,DownText,Black,White,Red,White);
     Btn_Up.OnClick:= @Btn_Up_OnClick;
     Btn_Down.OnClick:= @Btn_Down_OnClick;
     mx1:= X1;
     mx2:= X2;
     my1:= Y1;
     my2:= Y2;
     inherited Create(Parent, X1, Y1+1, X2-1, Y2-1);
end;

procedure TListBox.Add(Text: String);
begin
     Strings.Add(Text);
     Draw;
end;

procedure TListBox.Delete(Index: Integer);
begin
     If (Index > 0) and (Index < Strings.Count) then begin
        Strings.Delete(Index);
        Draw;
     end;
end;

function TListBox.GetSelectedText: String;
begin
     Result:='';
     If Selected > -1 then Result:= Strings[Selected];
end;

function TListBox.IndexOf(Text: String): Integer;
begin
     Result:= Strings.IndexOf(Text);
end;

function TListBox.GetText(Index: Integer): String;
begin
     Result:='';
     If (Index > 0) and (Index < Strings.Count) then begin
        Result:= Strings[Index];
     end;
end;

procedure TListBox.Draw;
Var
   i,n:Integer;
   displayText:String;

begin
     { Clear Current List }
     For i:=mY1+1 to mY2-1 do begin
         Screen.DrawXY(GetTag,mX1,i,BlankingPlate,Black,Black);
     end;
     { Draw New List }
     n:=position;
     For i:=mY1+1 to mY2-1 do begin
         If n <= Strings.Count-1 then begin
            displayText:= Strings[n];
            If Length(displayText) > Width then begin
               SetLength(displayText,(Width-2));
               displayText:= displayText+'..';
            end;
            While Length(displayText) < Width do begin
                displayText:=displayText+' ';
            end;
            If n = Selected then begin
               Screen.DrawXY(GetTag,mX1,i,displayText,White,Blue);
            end else begin
                Screen.DrawXY(GetTag,mX1,i,displayText,White,Black);
            end;
         end;
         inc(n);
     end;
end;

procedure TListBox.Btn_Up_OnClick;
begin
     Selected:=-1;
     If Position > 0 then begin
        Dec(Position);
     end;
     Draw;
end;

procedure TListBox.Btn_Down_OnClick;
begin
     Selected:=-1;
     If (Position + (Height-2)) < Strings.Count-1 then begin
        Inc(Position);
     end;
     Draw;
end;

procedure TListBox.CreateTexts;
Var
   LeftBuffer:String;
   RightBuffer:String;
   i:integer;

begin
     LeftBuffer:='';
     RightBuffer:='';
     While Length(' '+LeftBuffer+' '+RightBuffer+' ') < Width do begin
           LeftBuffer:=LeftBuffer+' ';
           RightBuffer:= RightBuffer+' ';
     end;
     UpText:= LeftBuffer+#24+RightBuffer;
     DownText:= LeftBuffer+#25+RightBuffer;
     For i:=0 to Length(UpText)+1 do begin
         BlankingPlate:=BlankingPlate+' ';
     end;
end;

procedure TListBox.List_OnClick;
Var
   X,Y:Integer;
   i,n:Integer;

begin
     X:= Screen.GetMouseX;
     Y:= Screen.GetMouseY;
     n:= position;
     For i:=mY1+1 to mY2-1 do begin
         If i = Y then begin
            if Strings.Count > n then Selected:=n;
         end;
         inc(n);
     end;
     Draw;
end;

procedure TListBox.SetVisible(Vis: Boolean);
begin
     btn_Up.Visible:= Vis;
     btn_Down.Visible:= Vis;
     inherited SetVisible(Vis);
end;

{ Callback Events }

procedure TListBox._OnKeyPress(Key: Char);
begin
     inherited _OnKeyPress(Key);
end;

procedure TListBox._OnMouseEnter;
begin
     inherited _OnMouseEnter;
end;

procedure TListBox._OnMouseLeave;
begin
     inherited _OnMouseLeave;
end;

procedure TListBox._OnClick;
begin
     List_OnClick;
     inherited _OnClick;
end;

procedure TListBox._OnLoseFocus;
begin
     inherited _OnLoseFocus;
end;

end.

